//+------------------------------------------------------------------+
//|                                 AllAveragesRibbonBar_v1 600+.mq4 |
//|                                Copyright  2015, TrendLaboratory |
//|            http://finance.groups.yahoo.com/group/TrendLaboratory |
//|                                   E-mail: igorad2003@yahoo.co.uk |
//+------------------------------------------------------------------+
#property copyright "Copyright  2015, TrendLaboratory"
#property link      "http://finance.groups.yahoo.com/group/TrendLaboratory"

#property indicator_separate_window
#property indicator_buffers 90
//#1
#property indicator_color1    clrGray
#property indicator_width1    1  
#property indicator_color2    clrLime
#property indicator_width2    1
#property indicator_color3    clrGreen
#property indicator_width3    1
#property indicator_color4    clrRed
#property indicator_width4    1
#property indicator_color5    clrMaroon
#property indicator_width5    1
//#2 
#property indicator_color6    clrGray
#property indicator_width6    1  
#property indicator_color7    clrLime
#property indicator_width7    1
#property indicator_color8    clrGreen
#property indicator_width8    1
#property indicator_color9    clrRed
#property indicator_width9    1
#property indicator_color10   clrMaroon
#property indicator_width10   1
//#3
#property indicator_color11   clrGray
#property indicator_width11   1  
#property indicator_color12   clrLime
#property indicator_width12   1
#property indicator_color13   clrGreen
#property indicator_width13   1
#property indicator_color14   clrRed
#property indicator_width14   1
#property indicator_color15   clrMaroon
#property indicator_width15   1
//#4 
#property indicator_color16   clrGray
#property indicator_width16   1  
#property indicator_color17   clrLime
#property indicator_width17   1
#property indicator_color18   clrGreen
#property indicator_width18   1
#property indicator_color19   clrRed
#property indicator_width19   1
#property indicator_color20   clrMaroon
#property indicator_width20   1
//#5
#property indicator_color21   clrGray
#property indicator_width21   1  
#property indicator_color22   clrLime
#property indicator_width22   1
#property indicator_color23   clrGreen
#property indicator_width23   1
#property indicator_color24   clrRed
#property indicator_width24   1
#property indicator_color25   clrMaroon
#property indicator_width25   1
//#6
#property indicator_color26   clrGray
#property indicator_width26   1  
#property indicator_color27   clrLime
#property indicator_width27   1
#property indicator_color28   clrGreen
#property indicator_width28   1
#property indicator_color29   clrRed
#property indicator_width29   1
#property indicator_color30   clrMaroon
#property indicator_width30   1
//#7 
#property indicator_color31   clrGray
#property indicator_width31   1  
#property indicator_color32   clrLime
#property indicator_width32   1
#property indicator_color33   clrGreen
#property indicator_width33   1
#property indicator_color34   clrRed
#property indicator_width34   1
#property indicator_color35   clrMaroon
#property indicator_width35   1
//#8
#property indicator_color36   clrGray
#property indicator_width36   1  
#property indicator_color37   clrLime
#property indicator_width37   1
#property indicator_color38   clrGreen
#property indicator_width38   1
#property indicator_color39   clrRed
#property indicator_width39   1
#property indicator_color40   clrMaroon
#property indicator_width40   1
//#9
#property indicator_color41   clrGray
#property indicator_width41   1  
#property indicator_color42   clrLime
#property indicator_width42   1
#property indicator_color43   clrGreen
#property indicator_width43   1
#property indicator_color44   clrRed
#property indicator_width44   1
#property indicator_color45   clrMaroon
#property indicator_width45   1
//#10
#property indicator_color46   clrGray
#property indicator_width46   1  
#property indicator_color47   clrLime
#property indicator_width47   1
#property indicator_color48   clrGreen
#property indicator_width48   1
#property indicator_color49   clrRed
#property indicator_width49   1
#property indicator_color50   clrMaroon
#property indicator_width50   1
//#11
#property indicator_color51   clrGray
#property indicator_width51   1  
#property indicator_color52   clrLime
#property indicator_width52   1
#property indicator_color53   clrGreen
#property indicator_width53   1
#property indicator_color54   clrRed
#property indicator_width54   1
#property indicator_color55   clrMaroon
#property indicator_width55   1
//#12
#property indicator_color56   clrGray
#property indicator_width56   1  
#property indicator_color57   clrLime
#property indicator_width57   1
#property indicator_color58   clrGreen
#property indicator_width58   1
#property indicator_color59   clrRed
#property indicator_width59   1
#property indicator_color60   clrMaroon
#property indicator_width60   1
//#13
#property indicator_color61   clrGray
#property indicator_width61   1  
#property indicator_color62   clrLime
#property indicator_width62   1
#property indicator_color63   clrGreen
#property indicator_width63   1
#property indicator_color64   clrRed
#property indicator_width64   1
#property indicator_color65   clrMaroon
#property indicator_width65   1
//#14
#property indicator_color66   clrGray
#property indicator_width66   1  
#property indicator_color67   clrLime
#property indicator_width67   1
#property indicator_color68   clrGreen
#property indicator_width68   1
#property indicator_color69   clrRed
#property indicator_width69   1
#property indicator_color70   clrMaroon
#property indicator_width70   1
//#15
#property indicator_color71   clrGray
#property indicator_width71   1  
#property indicator_color72   clrLime
#property indicator_width72   1
#property indicator_color73   clrGreen
#property indicator_width73   1
#property indicator_color74   clrRed
#property indicator_width74   1
#property indicator_color75   clrMaroon
#property indicator_width75   1
//#16
#property indicator_color76   clrGray
#property indicator_width76   1  
#property indicator_color77   clrLime
#property indicator_width77   1
#property indicator_color78   clrGreen
#property indicator_width78   1
#property indicator_color79   clrRed
#property indicator_width79   1
#property indicator_color80   clrMaroon
#property indicator_width80   1
//#17
#property indicator_color81   clrGray
#property indicator_width81   1  
#property indicator_color82   clrLime
#property indicator_width82   1
#property indicator_color83   clrGreen
#property indicator_width83   1
#property indicator_color84   clrRed
#property indicator_width84   1
#property indicator_color85   clrMaroon
#property indicator_width85   1
//#18
#property indicator_color86   clrGray
#property indicator_width86   1  
#property indicator_color87   clrLime
#property indicator_width87   1
#property indicator_color88   clrGreen
#property indicator_width88   1
#property indicator_color89   clrRed
#property indicator_width89   1
#property indicator_color90   clrMaroon
#property indicator_width90   1


//---- 
enum tf
{
   current        =     0,
   M1             =     1,
   M5             =     5,
   M15            =    15,
   M30            =    30,
   H1             =    60,
   H4             =   240,
   D1             =  1440,
   W1             = 10080,
   MN1            = 43200
};
extern tf      timeFrame   = current; 
enum _price
{
   close           =  0,
   open            =  1,
   high            =  2,
   low             =  3,
   median          =  4,
   typical         =  5,
   weightedClose   =  6,
   heikenAshiClose =  7,
   heikenAshiOpen  =  8,
   heikenAshiHigh  =  9,
   heikenAshiLow   = 10
};
extern _price  PriceMode    =    0;
extern int     Length1      =    5;
extern int     Length2      =   10;
extern int     Length3      =   15;
extern int     Length4      =   20;
extern int     Length5      =   25;
extern int     Length6      =   30;
extern int     Length7      =   35;
extern int     Length8      =   40;
extern int     Length9      =   45;
extern int     Length10     =   50;
extern int     Length11     =   55;
extern int     Length12     =   60;
extern int     Length13     =   65;
extern int     Length14     =   70;
extern int     Length15     =   75;
extern int     Length16     =   80;
extern int     Length17     =   85;
extern int     Length18     =   90;
extern int     Length19     =  100;
extern int     MA_Shift     =    0;
enum mamode
{
   SMA            =  0,
   EMA            =  1,
   Wilder         =  2,
   LWMA           =  3,
   SineWMA        =  4,
   TriMA          =  5,
   LSMA           =  6,
   SMMA           =  7,
   HMA            =  8,
   ZeroLagEMA     =  9,
   DEMA           = 10,
   T3_basic       = 11,   
   ITrend         = 12,
   Median         = 13,
   GeoMean        = 14,
   REMA           = 15,
   ILRS           = 16,
   IE_2           = 17,
   TriMAgen       = 18,
   VWMA           = 19,
   JSmooth        = 20,
   SMA_eq         = 21,
   ALMA           = 22,
   TEMA           = 23,
   T3             = 24,
   Laguerre       = 25,
   MD             = 26
};   
extern mamode  MA_Method    =    0;
extern int     ArrowCode    =  167;      // Arrow Code in Wingdings
extern int     CountBars    = 1000;      //Number of bars counted: 0-all bars    


double  avg1[],  upAvg11[],  upAvg12[],  dnAvg11[],  dnAvg12[];
double  avg2[],  upAvg21[],  upAvg22[],  dnAvg21[],  dnAvg22[];
double  avg3[],  upAvg31[],  upAvg32[],  dnAvg31[],  dnAvg32[];
double  avg4[],  upAvg41[],  upAvg42[],  dnAvg41[],  dnAvg42[];
double  avg5[],  upAvg51[],  upAvg52[],  dnAvg51[],  dnAvg52[]; 
double  avg6[],  upAvg61[],  upAvg62[],  dnAvg61[],  dnAvg62[];
double  avg7[],  upAvg71[],  upAvg72[],  dnAvg71[],  dnAvg72[];
double  avg8[],  upAvg81[],  upAvg82[],  dnAvg81[],  dnAvg82[];
double  avg9[],  upAvg91[],  upAvg92[],  dnAvg91[],  dnAvg92[];
double avg10[], upAvg101[], upAvg102[], dnAvg101[], dnAvg102[];
double avg11[], upAvg111[], upAvg112[], dnAvg111[], dnAvg112[];
double avg12[], upAvg121[], upAvg122[], dnAvg121[], dnAvg122[];
double avg13[], upAvg131[], upAvg132[], dnAvg131[], dnAvg132[];
double avg14[], upAvg141[], upAvg142[], dnAvg141[], dnAvg142[];
double avg15[], upAvg151[], upAvg152[], dnAvg151[], dnAvg152[]; 
double avg16[], upAvg161[], upAvg162[], dnAvg161[], dnAvg162[];
double avg17[], upAvg171[], upAvg172[], dnAvg171[], dnAvg172[];
double avg18[], upAvg181[], upAvg182[], dnAvg181[], dnAvg182[];

double iPrice[];


//----
double   tmp[][19][2], ma[19][3], mavg[19][2];
int      cBars, draw_begin, masize, TimeFrame, Price; 
string   IndicatorName, TF, short_name, maname;
datetime prevtime[19], prevavgtime;  
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
{
   TimeFrame = timeFrame;
   if(TimeFrame <= Period()) TimeFrame = Period();
   TF = EnumToString(timeFrame);
      
   IndicatorDigits(0);
//----
   Price  = PriceMode;
   maname = averageName(MA_Method,masize);
     
   IndicatorName = WindowExpertName(); 
   short_name = "[" + TF + "]("+ EnumToString(PriceMode) + "," + MA_Shift + ")";
   
   IndicatorShortName(IndicatorName + short_name);
      
   IndicatorBuffers(92); 
   setBuffers( 0, avg1, upAvg11, upAvg12, dnAvg11, dnAvg12,DRAW_ARROW,ArrowCode,MA_Shift,maname+"("+Length1+")" );
   setBuffers( 5, avg2, upAvg21, upAvg22, dnAvg21, dnAvg22,DRAW_ARROW,ArrowCode,MA_Shift,maname+"("+Length2+")" );
   setBuffers(10, avg3, upAvg31, upAvg32, dnAvg31, dnAvg32,DRAW_ARROW,ArrowCode,MA_Shift,maname+"("+Length3+")" );
   setBuffers(15, avg4, upAvg41, upAvg42, dnAvg41, dnAvg42,DRAW_ARROW,ArrowCode,MA_Shift,maname+"("+Length4+")" );
   setBuffers(20, avg5, upAvg51, upAvg52, dnAvg51, dnAvg52,DRAW_ARROW,ArrowCode,MA_Shift,maname+"("+Length5+")" );
   setBuffers(25, avg6, upAvg61, upAvg62, dnAvg61, dnAvg62,DRAW_ARROW,ArrowCode,MA_Shift,maname+"("+Length6+")" );
   setBuffers(30, avg7, upAvg71, upAvg72, dnAvg71, dnAvg72,DRAW_ARROW,ArrowCode,MA_Shift,maname+"("+Length7+")" );
   setBuffers(35, avg8, upAvg81, upAvg82, dnAvg81, dnAvg82,DRAW_ARROW,ArrowCode,MA_Shift,maname+"("+Length8+")" );
   setBuffers(40, avg9, upAvg91, upAvg92, dnAvg91, dnAvg92,DRAW_ARROW,ArrowCode,MA_Shift,maname+"("+Length9+")" );
   setBuffers(45,avg10,upAvg101,upAvg102,dnAvg101,dnAvg102,DRAW_ARROW,ArrowCode,MA_Shift,maname+"("+Length10+")");
   setBuffers(50,avg11,upAvg111,upAvg112,dnAvg111,dnAvg112,DRAW_ARROW,ArrowCode,MA_Shift,maname+"("+Length11+")");
   setBuffers(55,avg12,upAvg121,upAvg122,dnAvg121,dnAvg122,DRAW_ARROW,ArrowCode,MA_Shift,maname+"("+Length12+")");
   setBuffers(60,avg13,upAvg131,upAvg132,dnAvg131,dnAvg132,DRAW_ARROW,ArrowCode,MA_Shift,maname+"("+Length13+")");
   setBuffers(65,avg14,upAvg141,upAvg142,dnAvg141,dnAvg142,DRAW_ARROW,ArrowCode,MA_Shift,maname+"("+Length14+")");
   setBuffers(70,avg15,upAvg151,upAvg152,dnAvg151,dnAvg152,DRAW_ARROW,ArrowCode,MA_Shift,maname+"("+Length15+")");
   setBuffers(75,avg16,upAvg161,upAvg162,dnAvg161,dnAvg162,DRAW_ARROW,ArrowCode,MA_Shift,maname+"("+Length16+")");
   setBuffers(80,avg17,upAvg171,upAvg172,dnAvg171,dnAvg172,DRAW_ARROW,ArrowCode,MA_Shift,maname+"("+Length17+")");
   setBuffers(85,avg18,upAvg181,upAvg182,dnAvg181,dnAvg182,DRAW_ARROW,ArrowCode,MA_Shift,maname+"("+Length18+")");
   
   SetIndexBuffer(91,iPrice);
   
   if(CountBars == 0) cBars = iBars(NULL,TimeFrame)*TimeFrame/Period(); else cBars = CountBars*TimeFrame/Period();
  
   draw_begin = Bars - cBars;
   
   for(int i=0;i<=90;i++) SetIndexDrawBegin(i,draw_begin); 
//----   
   ArrayResize(tmp,masize);
      
   return(0);
}

//+------------------------------------------------------------------+
//| AllAveragesRibbonBar_v1 600+                                     |
//+------------------------------------------------------------------+
int start()
{
   int limit, y, shift, cnt_bars = IndicatorCounted(); 
   
   if(cnt_bars > 0) limit = Bars - cnt_bars - 1;
   if(cnt_bars < 0) return(0);    
   if(cnt_bars < 1) limit = Bars - 1;
  
//---- 
   
   if(TimeFrame != Period())
	{
   limit = MathMax(limit,TimeFrame/Period()+1);   
      
      for(shift = 0;shift < limit;shift++) 
      {	
      y = iBarShift(NULL,TimeFrame,Time[shift]);
            
      mtfAvg( 0,avg1 , upAvg11, upAvg12, dnAvg11, dnAvg12,shift,y);
      mtfAvg( 5,avg2 , upAvg21, upAvg22, dnAvg21, dnAvg22,shift,y);
      mtfAvg(10,avg3 , upAvg31, upAvg32, dnAvg31, dnAvg32,shift,y);
      mtfAvg(15,avg4 , upAvg41, upAvg42, dnAvg41, dnAvg42,shift,y);
      mtfAvg(20,avg5 , upAvg51, upAvg52, dnAvg51, dnAvg52,shift,y);
      mtfAvg(25,avg6 , upAvg61, upAvg62, dnAvg61, dnAvg62,shift,y);    
      mtfAvg(30,avg7 , upAvg71, upAvg72, dnAvg71, dnAvg72,shift,y);
      mtfAvg(35,avg8 , upAvg81, upAvg82, dnAvg81, dnAvg82,shift,y);
      mtfAvg(40,avg9 , upAvg91, upAvg92, dnAvg91, dnAvg92,shift,y);
      mtfAvg(45,avg10,upAvg101,upAvg102,dnAvg101,dnAvg102,shift,y);
      mtfAvg(50,avg11,upAvg111,upAvg112,dnAvg111,dnAvg112,shift,y);
      mtfAvg(55,avg12,upAvg121,upAvg122,dnAvg121,dnAvg122,shift,y);    
      mtfAvg(60,avg13,upAvg131,upAvg132,dnAvg131,dnAvg132,shift,y);
      mtfAvg(65,avg14,upAvg141,upAvg142,dnAvg141,dnAvg142,shift,y);    
      mtfAvg(70,avg15,upAvg151,upAvg152,dnAvg151,dnAvg152,shift,y);
      mtfAvg(75,avg16,upAvg161,upAvg162,dnAvg161,dnAvg162,shift,y);    
      mtfAvg(80,avg17,upAvg171,upAvg172,dnAvg171,dnAvg172,shift,y);
      mtfAvg(85,avg18,upAvg181,upAvg182,dnAvg181,dnAvg182,shift,y);    
      }  
	
	return(0);
	}
   else
   for(shift=limit;shift>=0;shift--) 
   {
      if(prevavgtime != Time[shift])
      {
      for(int i=0;i<19;i++) mavg[i][1] = mavg[i][0];
      prevavgtime = Time[shift];
      }
      
      if(Price <= 6) iPrice[shift] = iMA(NULL,0,1,0,0,Price,shift);   
      else
      if(Price > 6 && Price <= 10) iPrice[shift] = HeikenAshi(Price-7,cBars + Length19,shift);
   
   mavg[0][0]  = allAveragesOnArray( 0,iPrice,Length1 ,MA_Method,masize,cBars + Length19,shift);    
   mavg[1][0]  = allAveragesOnArray( 1,iPrice,Length2 ,MA_Method,masize,cBars + Length19,shift);
   mavg[2][0]  = allAveragesOnArray( 2,iPrice,Length3 ,MA_Method,masize,cBars + Length19,shift);
   mavg[3][0]  = allAveragesOnArray( 3,iPrice,Length4 ,MA_Method,masize,cBars + Length19,shift);
   mavg[4][0]  = allAveragesOnArray( 4,iPrice,Length5 ,MA_Method,masize,cBars + Length19,shift);
   mavg[5][0]  = allAveragesOnArray( 5,iPrice,Length6 ,MA_Method,masize,cBars + Length19,shift);
   mavg[6][0]  = allAveragesOnArray( 6,iPrice,Length7 ,MA_Method,masize,cBars + Length19,shift);
   mavg[7][0]  = allAveragesOnArray( 7,iPrice,Length8 ,MA_Method,masize,cBars + Length19,shift);
   mavg[8][0]  = allAveragesOnArray( 8,iPrice,Length9 ,MA_Method,masize,cBars + Length19,shift);
   mavg[9][0]  = allAveragesOnArray( 9,iPrice,Length10,MA_Method,masize,cBars + Length19,shift);
   mavg[10][0] = allAveragesOnArray(10,iPrice,Length11,MA_Method,masize,cBars + Length19,shift);
   mavg[11][0] = allAveragesOnArray(11,iPrice,Length12,MA_Method,masize,cBars + Length19,shift);
   mavg[12][0] = allAveragesOnArray(12,iPrice,Length13,MA_Method,masize,cBars + Length19,shift);
   mavg[13][0] = allAveragesOnArray(13,iPrice,Length14,MA_Method,masize,cBars + Length19,shift);
   mavg[14][0] = allAveragesOnArray(14,iPrice,Length15,MA_Method,masize,cBars + Length19,shift);
   mavg[15][0] = allAveragesOnArray(15,iPrice,Length16,MA_Method,masize,cBars + Length19,shift);
   mavg[16][0] = allAveragesOnArray(16,iPrice,Length17,MA_Method,masize,cBars + Length19,shift);
   mavg[17][0] = allAveragesOnArray(17,iPrice,Length18,MA_Method,masize,cBars + Length19,shift);
   mavg[18][0] = allAveragesOnArray(18,iPrice,Length19,MA_Method,masize,cBars + Length19,shift);
   
      
   avgColor( 0,mavg[0][0] ,mavg[0][1] ,mavg[18][0],avg1 ,upAvg11 ,upAvg12 ,dnAvg11 ,dnAvg12 ,shift);
   avgColor( 1,mavg[1][0] ,mavg[1][1] ,mavg[18][0],avg2 ,upAvg21 ,upAvg22 ,dnAvg21 ,dnAvg22 ,shift);
   avgColor( 2,mavg[2][0] ,mavg[2][1] ,mavg[18][0],avg3 ,upAvg31 ,upAvg32 ,dnAvg31 ,dnAvg32 ,shift);
   avgColor( 3,mavg[3][0] ,mavg[3][1] ,mavg[18][0],avg4 ,upAvg41 ,upAvg42 ,dnAvg41 ,dnAvg42 ,shift);
   avgColor( 4,mavg[4][0] ,mavg[4][1] ,mavg[18][0],avg5 ,upAvg51 ,upAvg52 ,dnAvg51 ,dnAvg52 ,shift);
   avgColor( 5,mavg[5][0] ,mavg[5][1] ,mavg[18][0],avg6 ,upAvg61 ,upAvg62 ,dnAvg61 ,dnAvg62 ,shift);    
   avgColor( 6,mavg[6][0] ,mavg[6][1] ,mavg[18][0],avg7 ,upAvg71 ,upAvg72 ,dnAvg71 ,dnAvg72 ,shift);
   avgColor( 7,mavg[7][0] ,mavg[7][1] ,mavg[18][0],avg8 ,upAvg81 ,upAvg82 ,dnAvg81 ,dnAvg82 ,shift);
   avgColor( 8,mavg[8][0] ,mavg[8][1] ,mavg[18][0],avg9 ,upAvg91 ,upAvg92 ,dnAvg91 ,dnAvg92 ,shift);
   avgColor( 9,mavg[9][0] ,mavg[9][1] ,mavg[18][0],avg10,upAvg101,upAvg102,dnAvg101,dnAvg102,shift);
   avgColor(10,mavg[10][0],mavg[10][1],mavg[18][0],avg11,upAvg111,upAvg112,dnAvg111,dnAvg112,shift);
   avgColor(11,mavg[11][0],mavg[11][1],mavg[18][0],avg12,upAvg121,upAvg122,dnAvg121,dnAvg122,shift);    
   avgColor(12,mavg[12][0],mavg[12][1],mavg[18][0],avg13,upAvg131,upAvg132,dnAvg131,dnAvg132,shift);
   avgColor(13,mavg[13][0],mavg[13][1],mavg[18][0],avg14,upAvg141,upAvg142,dnAvg141,dnAvg142,shift);    
   avgColor(14,mavg[14][0],mavg[14][1],mavg[18][0],avg15,upAvg151,upAvg152,dnAvg151,dnAvg152,shift);
   avgColor(15,mavg[15][0],mavg[15][1],mavg[18][0],avg16,upAvg161,upAvg162,dnAvg161,dnAvg162,shift);    
   avgColor(16,mavg[16][0],mavg[16][1],mavg[18][0],avg17,upAvg171,upAvg172,dnAvg171,dnAvg172,shift);
   avgColor(17,mavg[17][0],mavg[17][1],mavg[18][0],avg18,upAvg181,upAvg182,dnAvg181,dnAvg182,shift);    
   }
   
//---- 
   return(0);
}

//----
void setBuffers(int index,double& array1[],double& array2[],double& array3[],double& array4[],double& array5[],int style,int code,int shift,string name)
{
   SetIndexBuffer(index  ,array1); SetIndexStyle(index  ,style); SetIndexArrow(index  ,code); SetIndexShift(index  ,shift*TimeFrame/Period()); 
   SetIndexBuffer(index+1,array2); SetIndexStyle(index+1,style); SetIndexArrow(index+1,code); SetIndexShift(index+1,shift*TimeFrame/Period());
   SetIndexBuffer(index+2,array3); SetIndexStyle(index+2,style); SetIndexArrow(index+2,code); SetIndexShift(index+2,shift*TimeFrame/Period());
   SetIndexBuffer(index+3,array4); SetIndexStyle(index+3,style); SetIndexArrow(index+3,code); SetIndexShift(index+3,shift*TimeFrame/Period());
   SetIndexBuffer(index+4,array5); SetIndexStyle(index+4,style); SetIndexArrow(index+4,code); SetIndexShift(index+4,shift*TimeFrame/Period());
   SetIndexLabel (index  ,name  );         
}

void avgColor(int index,double avg,double prev,double avgref,double& oavg[],double& up1[],double& up2[],double& dn1[],double& dn2[],int bar)
{
   oavg[bar] = index;
   up1[bar] = EMPTY_VALUE; up2[bar] = EMPTY_VALUE;
   dn1[bar] = EMPTY_VALUE; dn2[bar] = EMPTY_VALUE;
   
   if(avg >= prev && avg > avgref) up1[bar] = index;
   else
   if(avg >= prev && avg < avgref) up2[bar] = index;
   else
   if(avg <= prev && avg < avgref) dn1[bar] = index;       
   else
   if(avg <  prev && avg > avgref) dn2[bar] = index;
} 

void mtfAvg(int index,double& avg[],double& up1[],double& up2[],double& dn1[],double& dn2[],int bar,int y)
{
   avg[bar] = iCustom(NULL,TimeFrame,IndicatorName,0,Price,Length1,Length2,Length3,Length4,Length5,Length6,Length7,Length8,Length9,Length10,Length11,Length12,Length13,Length14,Length15,Length16,Length17,Length18,Length19,MA_Shift,MA_Method,ArrowCode,CountBars,index  ,y);
   up1[bar] = iCustom(NULL,TimeFrame,IndicatorName,0,Price,Length1,Length2,Length3,Length4,Length5,Length6,Length7,Length8,Length9,Length10,Length11,Length12,Length13,Length14,Length15,Length16,Length17,Length18,Length19,MA_Shift,MA_Method,ArrowCode,CountBars,index+1,y);
   up2[bar] = iCustom(NULL,TimeFrame,IndicatorName,0,Price,Length1,Length2,Length3,Length4,Length5,Length6,Length7,Length8,Length9,Length10,Length11,Length12,Length13,Length14,Length15,Length16,Length17,Length18,Length19,MA_Shift,MA_Method,ArrowCode,CountBars,index+2,y);
   dn1[bar] = iCustom(NULL,TimeFrame,IndicatorName,0,Price,Length1,Length2,Length3,Length4,Length5,Length6,Length7,Length8,Length9,Length10,Length11,Length12,Length13,Length14,Length15,Length16,Length17,Length18,Length19,MA_Shift,MA_Method,ArrowCode,CountBars,index+3,y);
   dn2[bar] = iCustom(NULL,TimeFrame,IndicatorName,0,Price,Length1,Length2,Length3,Length4,Length5,Length6,Length7,Length8,Length9,Length10,Length11,Length12,Length13,Length14,Length15,Length16,Length17,Length18,Length19,MA_Shift,MA_Method,ArrowCode,CountBars,index+4,y);
}
//-----
string averageName(int mode,int& arraysize)
{   
   string ma_name = "";
   
   switch(mode)
   {
   case 1 : ma_name = "EMA"       ; break;
   case 2 : ma_name = "Wilder"    ; break;
   case 3 : ma_name = "LWMA"      ; break;
   case 4 : ma_name = "SineWMA"   ; break;
   case 5 : ma_name = "TriMA"     ; break;
   case 6 : ma_name = "LSMA"      ; break;
   case 7 : ma_name = "SMMA"      ; break;
   case 8 : ma_name = "HMA"       ; break;
   case 9 : ma_name = "ZeroLagEMA"; break;
   case 10: ma_name = "DEMA"      ; arraysize = 2; break;
   case 11: ma_name = "T3 basic"  ; arraysize = 6; break;
   case 12: ma_name = "InstTrend" ; break;
   case 13: ma_name = "Median"    ; break;
   case 14: ma_name = "GeoMean"   ; break;
   case 15: ma_name = "REMA"      ; break;
   case 16: ma_name = "ILRS"      ; break;
   case 17: ma_name = "IE/2"      ; break;
   case 18: ma_name = "TriMA_gen" ; break;
   case 19: ma_name = "VWMA"      ; break;
   case 20: ma_name = "JSmooth"   ; arraysize = 5; break;
   case 21: ma_name = "SMA_eq"    ; break;
   case 22: ma_name = "ALMA"      ; break;
   case 23: ma_name = "TEMA"      ; arraysize = 4; break;
   case 24: ma_name = "T3"        ; arraysize = 6; break;
   case 25: ma_name = "Laguerre"  ; arraysize = 4; break;
   case 26: ma_name = "MD"        ; break;
   default: ma_name = "SMA"       ; break;
   }
   
   return(ma_name);
}


double allAveragesOnArray(int index,double& price[],int period,int mode,int arraysize,int cbars,int bar)
{
   double MA[3];  
        
   if(prevtime[index] != Time[bar])
   {
   ma[index][2] = ma[index][1]; 
   ma[index][1] = ma[index][0]; 
   for(int i=0;i<arraysize;i++) tmp[i][index][1] = tmp[i][index][0];
    
   prevtime[index] = Time[bar]; 
   }
   
   for(i=0;i<3;i++) MA[i] = ma[index][i];   
   
   switch(mode)
   {
   case 1 : ma[index][0] = EMAOnArray(price[bar],ma[index][1],period,cbars,bar); break;
   case 2 : ma[index][0] = WilderOnArray(price[bar],ma[index][1],period,cbars,bar); break;  
   case 3 : ma[index][0] = LWMAOnArray(price,period,bar); break;
   case 4 : ma[index][0] = SineWMAOnArray(price,period,bar); break;
   case 5 : ma[index][0] = TriMAOnArray(price,period,bar); break;
   case 6 : ma[index][0] = LSMAOnArray(price,period,bar); break;
   case 7 : ma[index][0] = SMMAOnArray(price,ma[index][1],period,cbars,bar); break;
   case 8 : ma[index][0] = HMAOnArray(price,period,cbars,bar); break;
   case 9 : ma[index][0] = ZeroLagEMAOnArray(price,ma[index][1],period,cbars,bar); break;
   case 10: ma[index][0] = DEMAOnArray(index,0,price[bar],period,1,cbars,bar); break;
   case 11: ma[index][0] = T3_basicOnArray(index,0,price[bar],period,0.7,cbars,bar); break;
   case 12: ma[index][0] = ITrendOnArray(price,MA,period,cbars,bar); break;
   case 13: ma[index][0] = MedianOnArray(price,period,bar); break;
   case 14: ma[index][0] = GeoMeanOnArray(price,period,cbars,bar); break;
   case 15: ma[index][0] = REMAOnArray(price[bar],MA,period,0.5,cbars,bar); break;
   case 16: ma[index][0] = ILRSOnArray(price,period,bar); break;
   case 17: ma[index][0] = IE2OnArray(price,period,bar); break;
   case 18: ma[index][0] = TriMA_genOnArray(price,period,bar); break;
   case 19: ma[index][0] = VWMAOnArray(price,period,bar); break;
   case 20: ma[index][0] = JSmoothOnArray(index,0,price[bar],period,1,cbars,bar); break;
   case 21: ma[index][0] = SMA_eqOnArray(price,MA,period,cbars,bar); break;
   case 22: ma[index][0] = ALMAOnArray(price,period,0.85,8,bar); break;
   case 23: ma[index][0] = TEMAOnArray(index,price[bar],period,1,cbars,bar); break;
   case 24: ma[index][0] = T3OnArray(index,0,price[bar],period,0.7,cbars,bar); break;
   case 25: ma[index][0] = LaguerreOnArray(index,price[bar],period,4,cbars,bar); break;
   case 26: ma[index][0] = McGinleyOnArray(price[bar],ma[index][1],period,cbars,bar); break;
   default: ma[index][0] = SMAOnArray(price,period,bar); break;
   }
   
   return(ma[index][0]);
}

// MA_Method=0: SMA - Simple Moving Average
double SMAOnArray(double& array[],int per,int bar)
{
   double sum = 0;
   for(int i=0;i<per;i++) sum += array[bar+i];
   
   return(sum/per);
}                
// MA_Method=1: EMA - Exponential Moving Average
double EMAOnArray(double price,double prev,int per,int cbars,int bar)
{
   if(bar >= cbars - 2) double ema = price;
   else 
   ema = prev + 2.0/(1 + per)*(price - prev); 
   
   return(ema);
}
// MA_Method=2: Wilder - Wilder Exponential Moving Average
double WilderOnArray(double price,double prev,int per,int cbars,int bar)
{
   if(bar >= cbars - 2) double wilder = price; 
   else 
   wilder = prev + (price - prev)/per; 
   
   return(wilder);
}

// MA_Method=3: LWMA - Linear Weighted Moving Average 
double LWMAOnArray(double& array[],int per,int bar)
{
   double sum = 0, weight = 0;
   
      for(int i=0;i<per;i++)
      { 
      weight += (per - i);
      sum    += array[bar+i]*(per - i);
      }
   
   if(weight > 0) return(sum/weight); else return(0); 
} 

// MA_Method=4: SineWMA - Sine Weighted Moving Average
double SineWMAOnArray(double& array[],int per,int bar)
{
   double pi = 3.1415926535, sum = 0, weight = 0;
  
      for(int i=0;i<per;i++)
      { 
      weight += MathSin(pi*(i + 1)/(per + 1));
      sum    += array[bar+i]*MathSin(pi*(i + 1)/(per + 1)); 
      }
   
   if(weight > 0) return(sum/weight); else return(0); 
}

// MA_Method=5: TriMA - Triangular Moving Average
double TriMAOnArray(double& array[],int per,int bar)
{
   int len = MathCeil((per + 1)*0.5);
   double sum = 0;
   
   for(int i=0;i<len;i++) sum += SMAOnArray(array,len,bar+i);
         
   return(sum/len);
}

// MA_Method=6: LSMA - Least Square Moving Average (or EPMA, Linear Regression Line)
double LSMAOnArray(double& array[],int per,int bar)
{   
   double sum = 0;
   
   for(int i=per;i>=1;i--) sum += (i - (per + 1)/3.0)*array[bar+per-i];
   
   return(sum*6/(per*(per + 1)));
}

// MA_Method=7: SMMA - Smoothed Moving Average
double SMMAOnArray(double& array[],double prev,int per,int cbars,int bar)
{
   if(bar == cbars - per) double smma = SMAOnArray(array,per,bar);
   else 
   if(bar  < cbars - per)
   {
   double sum = 0;
   for(int i=0;i<per;i++) sum += array[bar+i+1];
   smma = (sum - prev + array[bar])/per;
   }
   
   return(smma);
}                

// MA_Method=8: HMA - Hull Moving Average by Alan Hull
double HMAOnArray(double& array[],int per,int cbars,int bar)
{
   double _tmp[];
   int len = MathSqrt(per);
   
   ArrayResize(_tmp,len);
   
   if(bar == cbars - per) double hma = array[bar]; 
   else
   if(bar < cbars - per)
   {
   for(int i=0;i<len;i++) _tmp[i] = 2*LWMAOnArray(array,per/2,bar+i) - LWMAOnArray(array,per,bar+i);  
   hma = LWMAOnArray(_tmp,len,0); 
   }  

   return(hma);
}

// MA_Method=9: ZeroLagEMA - Zero-Lag Exponential Moving Average
double ZeroLagEMAOnArray(double& price[],double prev,int per,int cbars,int bar)
{
   int lag = 0.5*(per - 1); 
   double alpha = 2.0/(1 + per); 
      
   if(bar >= cbars - lag) double zema = price[bar];
   else 
   zema = alpha*(2*price[bar] - price[bar+lag]) + (1 - alpha)*prev;
   
   return(zema);
}

// MA_Method=10: DEMA - Double Exponential Moving Average by Patrick Mulloy
double DEMAOnArray(int index,int num,double price,double per,double v,int cbars,int bar)
{
   double alpha = 2.0/(1 + per);
   
   if(bar == cbars - 2) {double dema = price; tmp[num][index][0] = dema; tmp[num+1][index][0] = dema;}
   else 
   if(bar <  cbars - 2) 
   {
   tmp[num  ][index][0] = tmp[num  ][index][1] + alpha*(price              - tmp[num  ][index][1]); 
   tmp[num+1][index][0] = tmp[num+1][index][1] + alpha*(tmp[num][index][0] - tmp[num+1][index][1]); 
   dema                 = tmp[num  ][index][0]*(1+v) - tmp[num+1][index][0]*v;
   }
   
   return(dema);
}

// MA_Method=11: T3 by T.Tillson
double T3_basicOnArray(int index,int num,double price,int per,double v,int cbars,int bar)
{
   double dema1, dema2;
   
   if(bar == cbars - 2) 
   {
   double T3 = price; 
   for(int k=0;k<6;k++) tmp[num+k][index][0] = price;
   }
   else 
   if(bar < cbars - 2) 
   {
   dema1 = DEMAOnArray(index,num  ,price,per,v,cbars,bar); 
   dema2 = DEMAOnArray(index,num+2,dema1,per,v,cbars,bar); 
   T3    = DEMAOnArray(index,num+4,dema2,per,v,cbars,bar);
   }
   
   return(T3);
}

// MA_Method=12: ITrend - Instantaneous Trendline by J.Ehlers
double ITrendOnArray(double& price[],double& array[],int per,int cbars,int bar)
{
   double alpha = 2.0/(per + 1);
   if(bar > cbars - 7) double it = (alpha - 0.25*alpha*alpha)*price[bar] + 0.5*alpha*alpha*price[bar+1] 
                                 - (alpha - 0.75*alpha*alpha)*price[bar+2] + 2*(1 - alpha)*array[bar+1] 
                                 - (1 - alpha)*(1 - alpha)*array[bar+2];
   else it = (price[bar] + 2*price[bar+1] + price[bar+2])/4;
   
   return(it);
}
// MA_Method=13: Median - Moving Median
double MedianOnArray(double& price[],int per,int bar)
{
   double array[];
   ArrayResize(array,per);
   
   for(int i=0;i<per;i++) array[i] = price[bar+i];
   ArraySort(array,WHOLE_ARRAY,0,MODE_DESCEND);
   
   int num = MathRound((per - 1)*0.5); 
   if(MathMod(per,2) > 0) double median = array[num]; else median = 0.5*(array[num] + array[num+1]);
    
   return(median); 
}

// MA_Method=14: GeoMean - Geometric Mean
double GeoMeanOnArray(double& price[],int per,int cbars,int bar)
{
   if(bar < cbars - per)
   { 
   double gmean = MathPow(price[bar],1.0/per); 
   for(int i=1;i<per;i++) gmean *= MathPow(price[bar+i],1.0/per); 
   }
   else gmean = SMAOnArray(price,per,bar);
   
   return(gmean);
}

// MA_Method=15: REMA - Regularized EMA by Chris Satchwell 
double REMAOnArray(double price,double& array[],int per,double lambda,int cbars,int bar)
{
   double alpha =  2.0/(per + 1);
   
   if(bar >= cbars - 3) double rema = price;
   else 
   rema = (array[1]*(1 + 2*lambda) + alpha*(price - array[1]) - lambda*array[2])/(1 + lambda); 
   
   return(rema);
}
// MA_Method=16: ILRS - Integral of Linear Regression Slope 
double ILRSOnArray(double& price[],int per,int bar)
{
   double sum  = per*(per - 1)*0.5;
   double sum2 = (per - 1)*per*(2*per - 1)/6.0;
     
   double sum1 = 0;
   double sumy = 0;
      for(int i=0;i<per;i++)
      { 
      sum1 += i*price[bar+i];
      sumy += price[bar+i];
      }
   double num1 = per*sum1 - sum*sumy;
   double num2 = sum*sum - per*sum2;
   
   if(num2 != 0) double slope = num1/num2; else slope = 0; 
   double ilrs = slope + SMAOnArray(price,per,bar);
   
   return(ilrs);
}
// MA_Method=17: IE/2 - Combination of LSMA and ILRS 
double IE2OnArray(double& price[],int per,int bar)
{
   double ie = 0.5*(ILRSOnArray(price,per,bar) + LSMAOnArray(price,per,bar));
      
   return(ie); 
}
 
// MA_Method=18: TriMAgen - Triangular Moving Average Generalized by J.Ehlers
double TriMA_genOnArray(double& array[],int per,int bar)
{
   int len1 = MathFloor((per + 1)*0.5);
   int len2 = MathCeil ((per + 1)*0.5);
   double sum = 0;
   
   for(int i = 0;i < len2;i++) sum += SMAOnArray(array,len1,bar+i);
   
   return(sum/len2);
}

// MA_Method=19: VWMA - Volume Weighted Moving Average 
double VWMAOnArray(double& array[],int per,int bar)
{
   double sum = 0, weight = 0;
   
      for(int i=0;i<per;i++)
      { 
      weight += Volume[bar+i];
      sum    += array[bar+i]*Volume[bar+i];
      }
   
   if(weight > 0) return(sum/weight); else return(0); 
} 

// MA_Method=20: JSmooth - Smoothing by Mark Jurik
double JSmoothOnArray(int index,int num,double price,int per,double power,int cbars,int bar)
{
   double beta  = 0.45*(per - 1)/(0.45*(per - 1) + 2);
	double alpha = MathPow(beta,power);
	
	if(bar == cbars - 2) {tmp[num+4][index][0] = price; tmp[num+0][index][0] = price; tmp[num+2][index][0] = price;}
	else 
   if(bar <  cbars - 2) 
   {
	tmp[num+0][index][0] = (1 - alpha)*price + alpha*tmp[num+0][index][1];
	tmp[num+1][index][0] = (price - tmp[num+0][index][0])*(1-beta) + beta*tmp[num+1][index][1];
	tmp[num+2][index][0] = tmp[num+0][index][0] + tmp[num+1][index][0];
	tmp[num+3][index][0] = (tmp[num+2][index][0] - tmp[num+4][index][1])*MathPow((1-alpha),2) + MathPow(alpha,2)*tmp[num+3][index][1];
	tmp[num+4][index][0] = tmp[num+4][index][1] + tmp[num+3][index][0]; 
   }
   return(tmp[num+4][index][0]);
}

// MA_Method=21: SMA_eq     - Simplified SMA
double SMA_eqOnArray(double& price[],double& array[],int per,int cbars,int bar)
{
   if(bar == cbars - per) double sma = SMAOnArray(price,per,bar);
   else 
   if(bar <  cbars - per) sma = (price[bar] - price[bar+per])/per + array[1]; 
   
   return(sma);
}                        		

// MA_Method=22: ALMA by Arnaud Legoux / Dimitris Kouzis-Loukas / Anthony Cascino
double ALMAOnArray(double& price[],int per,double offset,double sigma,int bar)
{
   double m = MathFloor(offset*(per - 1)), s = per/sigma, w, sum = 0, wsum = 0;		
	
	for (int i=0;i<per;i++) 
	{
	w     = MathExp(-((i - m)*(i - m))/(2*s*s));
   wsum += w;
   sum  += price[bar+(per-1-i)]*w; 
   }
   
   if(wsum != 0) return(sum/wsum); else return(0);
}   

// MA_Method=23: TEMA - Triple Exponential Moving Average by Patrick Mulloy
double TEMAOnArray(int index,double price,int per,double v,int cbars,int bar)
{
   double alpha = 2.0/(per+1);
	
	if(bar == cbars - 2) {tmp[0][index][0] = price; tmp[1][index][0] = price; tmp[2][index][0] = price;}
	else 
   if(bar <  cbars - 2) 
   {
	tmp[0][index][0] = tmp[0][index][1] + alpha *(price            - tmp[0][index][1]);
	tmp[1][index][0] = tmp[1][index][1] + alpha *(tmp[0][index][0] - tmp[1][index][1]);
	tmp[2][index][0] = tmp[2][index][1] + alpha *(tmp[1][index][0] - tmp[2][index][1]);
	tmp[3][index][0] = tmp[0][index][0] + v*(tmp[0][index][0] + v*(tmp[0][index][0]-tmp[1][index][0]) - tmp[1][index][0] - v*(tmp[1][index][0] - tmp[2][index][0])); 
	}
   
   return(tmp[3][index][0]);
}

// MA_Method=24: T3 by T.Tillson (correct version) 
double T3OnArray(int index,int num,double price,int per,double v,int cbars,int bar)
{
   double len = MathMax((per + 5.0)/3.0 - 1,1), dema1, dema2;
   
   if(bar == cbars - 2) 
   {
   double T3 = price; 
   for(int k=0;k<6;k++) tmp[num+k][index][0] = T3;
   }
   else 
   if(bar < cbars - 2) 
   {
   dema1 = DEMAOnArray(index,num  ,price,len,v,cbars,bar); 
   dema2 = DEMAOnArray(index,num+2,dema1,len,v,cbars,bar); 
   T3    = DEMAOnArray(index,num+4,dema2,len,v,cbars,bar);
   }
      
   return(T3);
}

// MA_Method=25: Laguerre filter by J.Ehlers
double LaguerreOnArray(int index,double price,int per,int order,int cbars,int bar)
{
   double gamma = 1 - 10.0/(per + 9);
   double aPrice[];
   
   ArrayResize(aPrice,order);
   
   for(int i=0;i<order;i++)
   {
      if(bar >= cbars - order) tmp[i][index][0] = price;
      else
      {
         if(i == 0) tmp[i][index][0] = (1 - gamma)*price + gamma*tmp[i][index][1];
         else
         tmp[i][index][0] = -gamma * tmp[i-1][index][0] + tmp[i-1][index][1] + gamma * tmp[i][index][1];
      
      aPrice[i] = tmp[i][index][0];
      }
   }
   double laguerre = TriMA_genOnArray(aPrice,order,0);  

   return(laguerre);
}

// MA_Method=26:  MD - McGinley Dynamic
double McGinleyOnArray(double price,double prev,int per,int cbars,int bar)
{
   if(bar == cbars - 2) double md = price;
   else 
   if(bar <  cbars - 2) 
      if(prev != 0) md = prev + (price - prev)/(per*MathPow(price/prev,4)/2); 
      else md = price;

   return(md);
}

// HeikenAshi Price:  7 - Close,8 - Open,9 - High,10 - Low 
double   haClose[2], haOpen[2], haHigh[2], haLow[2];
datetime prevhatime;

double HeikenAshi(int price,int cbars,int bar)
{ 
   if(prevhatime != Time[bar])
   {
   haClose[1] = haClose[0];
   haOpen [1] = haOpen [0];
   haHigh [1] = haHigh [0];
   haLow  [1] = haLow  [0];
   prevhatime = Time[bar];
   }
   
   if(bar == cbars - 1) 
   {
   haClose[0] = Close[bar];
   haOpen [0] = Open [bar];
   haHigh [0] = High [bar];
   haLow  [0] = Low  [bar];
   }
   else
   {
   haClose[0] = (Open[bar] + High[bar] + Low[bar] + Close[bar])/4;
   haOpen [0] = (haOpen[1] + haClose[1])/2;
   haHigh [0] = MathMax(High[bar],MathMax(haOpen[0],haClose[0]));
   haLow  [0] = MathMin(Low [bar],MathMin(haOpen[0],haClose[0]));
   }
   
   switch(price)
   {
   case  0: return(haClose[0]); break;
   case  1: return(haOpen [0]); break;
   case  2: return(haHigh [0]); break;
   case  3: return(haLow  [0]); break;
   default: return(haClose[0]); break;
   }
}


